#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <cstdlib>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <map>
#include "err.h"

using namespace std;

namespace Server
{
    const static uint16_t server_port = 1010;
    class Udpserver
    {
    public:
        Udpserver(uint16_t port = server_port)
            : _port(port)
        {
            cout << "server addr:" << _port << endl;
        }
        void Init()
        {
            // 1.创建socket接口(ipv4 SOCK_DGRAM支持数据报(无连接的、不可靠的
            // 固定最大长度)
            _sock = socket(AF_INET, SOCK_DGRAM, 0);
            if (_sock < 0)
            {
                cerr << "create socket error:" << strerror(errno) << endl;
                exit(1);
            }
            cout << "create socket error:" << _sock << endl;

            // 2.给服务器指明IP(??)和port
            struct sockaddr_in local; // 文件头
            // 这个local 在哪里定义呢？在用户空间的特定函数的栈帧上，不在内核

            // 设为全0
            bzero(&local, sizeof(local));

            local.sin_family = AF_INET;    // 设置ipv4
            local.sin_port = htons(_port); // 设置端口号

            // htons()在主机字节和网络字节之间转换值

            local.sin_addr.s_addr = INADDR_ANY; // 链接主机任意IP

            // inet_addr用于将一个点分十进制表示的IP地址转换为网络字节序的32位无符号整数
            // local.sin_addr.s_addr 结构体里面还有一个存储32位字节的结构体
            if (bind(_sock, (struct sockaddr *)&local, sizeof(local) < 0))
            {
                cerr << "bind socker fail:" << strerror(errno) << endl;
                exit(2);
            }

            cout << "bind socket success: " << _sock << endl;
        }

        void Start()
        {
            char buf[2048];
            while (true)
            {
                struct sockaddr_in peer;      // IP+Port
                socklen_t len = sizeof(peer); // 结构体大小
                int n = recvfrom(_sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&peer, &len);
                // 收数据
                if (n > 0)
                    buf[n] = 0;
                else
                    continue;

                string clientip = inet_ntoa(peer.sin_addr); // 将网络字节序的IP转换成点分十进制
                uint16_t clientport = ntohs(peer.sin_port); // 主机字节转网络字节
                cout << clientip << "-" << clientport << "#" << buf << endl;

                cout << "get message:" << buf << endl;

                //创建任务检查
                // string name=clientip;
                // name+="-";
                // name+=to_string(clientport);

                // addUser(name,pecer);
                


                // 发数据
                sendto(_sock, buf, strlen(buf), 0, (struct sockaddr *)&peer, sizeof(peer));
            }
        }

        ~Udpserver() {}

    private:
        int _sock;
        uint16_t _port;
        // string _ip;
        // unordered_map<string, struct sockaddr_in> onlineuser;
    };

}